/*
 * orderinfo_dao.c
 *
 *  Created on: 2013-2-15
 *      Author: panqiuhui
 */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <mysql.h>

#include "../head/dao/orderinfo_dao.h"

extern MYSQL_STMT *get_orderinfo_by_buy_date_stmt;
extern MYSQL_STMT *get_orderinfo_by_buy_date_with_orderID_stmt;
extern MYSQL_STMT *get_orderinfo_by_buy_date_with_trainID_stmt;
extern MYSQL_STMT *get_orderinfo_by_buy_date_with_all_stmt;
extern MYSQL_STMT *get_orderinfo_by_depart_date_stmt;
extern MYSQL_STMT *get_orderinfo_by_depart_date_with_orderID_stmt;
extern MYSQL_STMT *get_orderinfo_by_depart_date_with_trainID_stmt;
extern MYSQL_STMT *get_orderinfo_by_depart_date_with_all_stmt;
extern MYSQL_STMT *delete_orderinfo_stmt;

enum {
	OUTPUT_TABLE_ORDERS_SELECT_ORDERID = 0,
	OUTPUT_TABLE_ORDERS_SELECT_TRAINID,
	OUTPUT_TABLE_ORDERS_SELECT_COMPARTMENTNUM,
	OUTPUT_TABLE_ORDERS_SELECT_SEATNUM,
	OUTPUT_TABLE_ORDERS_SELECT_NAME,
	OUTPUT_TABLE_ORDERS_SELECT_CREDITTYPE,
	OUTPUT_TABLE_ORDERS_SELECT_CREDITID,
	OUTPUT_TABLE_ORDERS_SELECT_DEPARTDATE,
	OUTPUT_TABLE_ORDERS_SELECT_DEPARTSTATION,
	OUTPUT_TABLE_ORDERS_SELECT_ARRIVESTATION,
	OUTPUT_TABLE_ORDERS_SELECT_PRICE,
	OUTPUT_TABLE_ORDERS_SELECT_COLUMN_NUM
};

enum {
	INPUT_TABLE_ORDERS_SELECT_USERNAME = 0,
	INPUT_TABLE_ORDERS_SELECT_STARTDATE = 1,
	INPUT_TABLE_ORDERS_SELECT_ENDDATE = 2,
	INPUT_TABLE_ORDERS_SELECT_ORDERID = 3,
	INPUT_TABLE_ORDERS_SELECT_TRAINID_SINGLE = 3,
	INPUT_TABLE_ORDERS_SELECT_TRAINID = 4,
	INPUT_TABLE_ORDERS_SELECT_COLUMN_NUM_ALL = 5
};

enum {
	INPUT_TABLE_ORDERS_DELETE_ORDERID = 0,
	INPUT_TABLE_ORDERS_DELETE_USERNAME,
	INPUT_TABLE_ORDERS_DELETE_COLUMN_NUM
};

//删除订单，成功返回true，失败返回false
bool refund_order(struct orderinfo_refund_request *request,
		const OrderList *orderlist) {
	bool result = true;
	//设置输入的参数信息
	MYSQL_BIND input_bind[INPUT_TABLE_ORDERS_DELETE_COLUMN_NUM];
	int input_orderID;
	char input_username[ORDERS_USERNAME_LEN];
	unsigned long input_username_len;

	memset(input_bind, 0, sizeof(input_bind));
	input_bind[INPUT_TABLE_ORDERS_DELETE_ORDERID].buffer_type = MYSQL_TYPE_LONG;
	input_bind[INPUT_TABLE_ORDERS_DELETE_ORDERID].buffer = &input_orderID;
	input_bind[INPUT_TABLE_ORDERS_DELETE_ORDERID].is_null = 0;

	input_bind[INPUT_TABLE_ORDERS_DELETE_USERNAME].buffer_type =
			MYSQL_TYPE_STRING;
	input_bind[INPUT_TABLE_ORDERS_DELETE_USERNAME].buffer = input_username;
	input_bind[INPUT_TABLE_ORDERS_DELETE_USERNAME].buffer_length =
			ORDERS_USERNAME_LEN;
	input_bind[INPUT_TABLE_ORDERS_DELETE_USERNAME].is_null = 0;
	input_bind[INPUT_TABLE_ORDERS_DELETE_USERNAME].length = &input_username_len;

	OrderNode *node = *orderlist;
	while (node != NULL ) {
		OrderItem item = node->item;
		sscanf(item.orderID, "%d", &input_orderID);
		sscanf(request->username, "%s", input_username);
		input_username_len = strlen(input_username);

		if (mysql_stmt_bind_param(delete_orderinfo_stmt, input_bind)) {
			fprintf(stderr,
					"delete_orderinfo_stmt mysql_stmt_bind_param() failed\n");
			fprintf(stderr, "%s\n", mysql_stmt_error(delete_orderinfo_stmt));
			exit(EXIT_FAILURE);
		}

		if (mysql_stmt_execute(delete_orderinfo_stmt)) {
			fprintf(stderr,
					"delete_orderinfo_stmt mysql_stmt_execute(), failed\n");
			fprintf(stderr, "%s\n", mysql_stmt_error(delete_orderinfo_stmt));
			exit(EXIT_FAILURE);
		}

		int affected_rows = mysql_stmt_affected_rows(delete_orderinfo_stmt);
		fprintf(stdout, "delete_orderinfo_stmt total affected rows: %lu\n",
				(unsigned long) affected_rows);
		if (affected_rows != 1) {
			result = false;
			break;
		}
		node = node->next;
	}

	return result;
}

//查找订单，找到的话返回true，并将结果添加到链表orderlist中，失败返回false
bool search_order(const struct orderinfo_search_request *request,
		OrderList *orderlist) {
	bool result = true;
	//设置输入的参数信息
	MYSQL_BIND input_bind[INPUT_TABLE_ORDERS_SELECT_COLUMN_NUM_ALL];
	char input_username[ORDERS_USERNAME_LEN];
	unsigned long input_username_len;
	MYSQL_TIME input_startdate;
	MYSQL_TIME input_enddate;
	int input_orderID;
	char input_trainID[ORDERS_TRAINID_LEN];
	unsigned long input_trainID_len;

	memset(input_bind, 0, sizeof(input_bind));
	input_bind[INPUT_TABLE_ORDERS_SELECT_USERNAME].buffer_type =
			MYSQL_TYPE_STRING;
	input_bind[INPUT_TABLE_ORDERS_SELECT_USERNAME].buffer = input_username;
	input_bind[INPUT_TABLE_ORDERS_SELECT_USERNAME].buffer_length =
			ORDERS_USERNAME_LEN;
	input_bind[INPUT_TABLE_ORDERS_SELECT_USERNAME].is_null = 0;
	input_bind[INPUT_TABLE_ORDERS_SELECT_USERNAME].length = &input_username_len;

	input_bind[INPUT_TABLE_ORDERS_SELECT_STARTDATE].buffer_type =
			MYSQL_TYPE_DATE;
	input_bind[INPUT_TABLE_ORDERS_SELECT_STARTDATE].buffer = &input_startdate;
	input_bind[INPUT_TABLE_ORDERS_SELECT_STARTDATE].is_null = 0;
	input_bind[INPUT_TABLE_ORDERS_SELECT_STARTDATE].length = 0;

	input_bind[INPUT_TABLE_ORDERS_SELECT_ENDDATE].buffer_type = MYSQL_TYPE_DATE;
	input_bind[INPUT_TABLE_ORDERS_SELECT_ENDDATE].buffer = &input_enddate;
	input_bind[INPUT_TABLE_ORDERS_SELECT_ENDDATE].is_null = 0;
	input_bind[INPUT_TABLE_ORDERS_SELECT_ENDDATE].length = 0;

	memset(input_username, 0, sizeof(input_username));
	strncpy(input_username, request->username, strlen(request->username));
	input_username_len = strlen(input_username);

	int year;
	int month;
	int day;
	sscanf(request->startdate, "%04d-%02d-%02d", &year, &month, &day);
	input_startdate.year = year;
	input_startdate.month = month;
	input_startdate.day = day;

	sscanf(request->enddate, "%04d-%02d-%02d", &year, &month, &day);
	input_enddate.year = year;
	input_enddate.month = month;
	input_enddate.day = day;

	int orderID_len = strlen(request->orderID);
	int trainID_len = strlen(request->trainID);

	MYSQL_STMT * stmt_selected;

	if (orderID_len == 0) {
		if (trainID_len == 0) {
			if (request->order_search_type == ORDER_SEARCH_TYPE_BUY_DATE) {
				stmt_selected = get_orderinfo_by_buy_date_stmt;
			} else {
				stmt_selected = get_orderinfo_by_depart_date_stmt;
			}
		} else {
			if (request->order_search_type == ORDER_SEARCH_TYPE_BUY_DATE) {
				stmt_selected = get_orderinfo_by_buy_date_with_trainID_stmt;
			} else {
				stmt_selected = get_orderinfo_by_depart_date_with_trainID_stmt;
			}
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID_SINGLE].buffer_type =
					MYSQL_TYPE_STRING;
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID_SINGLE].buffer =
					input_trainID;
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID_SINGLE].buffer_length =
					ORDERS_TRAINID_LEN;
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID_SINGLE].is_null = 0;
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID_SINGLE].length =
					&input_trainID_len;
			memset(input_trainID, 0, sizeof(input_trainID));
			strncpy(input_trainID, request->trainID, trainID_len);
			input_trainID_len = strlen(input_trainID);
		}
	} else {
		if (trainID_len == 0) {
			if (request->order_search_type == ORDER_SEARCH_TYPE_BUY_DATE) {
				stmt_selected = get_orderinfo_by_buy_date_with_orderID_stmt;
			} else {
				stmt_selected = get_orderinfo_by_depart_date_with_orderID_stmt;
			}
			input_bind[INPUT_TABLE_ORDERS_SELECT_ORDERID].buffer_type =
					MYSQL_TYPE_LONG;
			input_bind[INPUT_TABLE_ORDERS_SELECT_ORDERID].buffer =
					&input_orderID;
			input_bind[INPUT_TABLE_ORDERS_SELECT_ORDERID].is_null = 0;
			sscanf(request->orderID, "%d", &input_orderID);
		} else {
			if (request->order_search_type == ORDER_SEARCH_TYPE_BUY_DATE) {
				stmt_selected = get_orderinfo_by_buy_date_with_all_stmt;
			} else {
				stmt_selected = get_orderinfo_by_depart_date_with_all_stmt;
			}
			input_bind[INPUT_TABLE_ORDERS_SELECT_ORDERID].buffer_type =
					MYSQL_TYPE_LONG;
			input_bind[INPUT_TABLE_ORDERS_SELECT_ORDERID].buffer =
					&input_orderID;
			input_bind[INPUT_TABLE_ORDERS_SELECT_ORDERID].is_null = 0;

			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID].buffer_type =
					MYSQL_TYPE_STRING;
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID].buffer =
					input_trainID;
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID].buffer_length =
					ORDERS_TRAINID_LEN;
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID].is_null = 0;
			input_bind[INPUT_TABLE_ORDERS_SELECT_TRAINID].length =
					&input_trainID_len;

			sscanf(request->orderID, "%d", &input_orderID);

			memset(input_trainID, 0, sizeof(input_trainID));
			strncpy(input_trainID, request->trainID, trainID_len);
			input_trainID_len = strlen(input_trainID);
		}
	}

	//设置输出的参数信息
	MYSQL_BIND output_bind[OUTPUT_TABLE_ORDERS_SELECT_COLUMN_NUM];
	int output_orderID;
	char output_trainID[ORDERS_TRAINID_LEN];
	int output_compartmentNum;
	int output_seatNum;
	char output_name[ORDERS_NAME_LEN];
	char output_creditType[ORDERS_CREDIT_TYPE_LEN];
	char output_creditID[ORDERS_CREDIT_ID_LEN];
	MYSQL_TIME output_departdate;
	char output_departstation[ORDERS_DEPART_STATION_LEN];
	char output_arrivestation[ORDERS_ARRIVE_STATION_LEN];
	float output_price;
	my_bool output_is_null[OUTPUT_TABLE_ORDERS_SELECT_COLUMN_NUM];
	my_bool output_error[OUTPUT_TABLE_ORDERS_SELECT_COLUMN_NUM];
	unsigned long output_length[OUTPUT_TABLE_ORDERS_SELECT_COLUMN_NUM];

	memset(output_bind, 0, sizeof(output_bind));

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_ORDERID].buffer_type =
			MYSQL_TYPE_LONG;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_ORDERID].buffer =
			(char *) &output_orderID;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_TRAINID].buffer_type =
			MYSQL_TYPE_STRING;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_TRAINID].buffer = output_trainID;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_TRAINID].buffer_length =
			ORDERS_TRAINID_LEN;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_COMPARTMENTNUM].buffer_type =
			MYSQL_TYPE_LONG;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_COMPARTMENTNUM].buffer =
			(char *) &output_compartmentNum;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_SEATNUM].buffer_type =
			MYSQL_TYPE_LONG;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_SEATNUM].buffer =
			(char *) &output_seatNum;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_NAME].buffer_type =
			MYSQL_TYPE_STRING;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_NAME].buffer = output_name;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_NAME].buffer_length =
			ORDERS_NAME_LEN;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_CREDITTYPE].buffer_type =
			MYSQL_TYPE_STRING;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_CREDITTYPE].buffer =
			output_creditType;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_CREDITTYPE].buffer_length =
			ORDERS_CREDIT_TYPE_LEN;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_CREDITID].buffer_type =
			MYSQL_TYPE_STRING;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_CREDITID].buffer = output_creditID;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_CREDITID].buffer_length =
			ORDERS_CREDIT_ID_LEN;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_DEPARTDATE].buffer_type =
			MYSQL_TYPE_DATE;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_DEPARTDATE].buffer =
			&output_departdate;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_DEPARTSTATION].buffer_type =
			MYSQL_TYPE_STRING;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_DEPARTSTATION].buffer =
			output_departstation;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_DEPARTSTATION].buffer_length =
			ORDERS_DEPART_STATION_LEN;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_ARRIVESTATION].buffer_type =
			MYSQL_TYPE_STRING;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_ARRIVESTATION].buffer =
			output_arrivestation;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_ARRIVESTATION].buffer_length =
			ORDERS_ARRIVE_STATION_LEN;

	output_bind[OUTPUT_TABLE_ORDERS_SELECT_PRICE].buffer_type =
			MYSQL_TYPE_FLOAT;
	output_bind[OUTPUT_TABLE_ORDERS_SELECT_PRICE].buffer = &output_price;

	int i = 0;
	for (i = 0; i < OUTPUT_TABLE_ORDERS_SELECT_COLUMN_NUM; i++) {
		output_bind[i].is_null = &output_is_null[i];
		output_bind[i].length = &output_length[i];
		output_bind[i].error = &output_error[i];
	}

	if (mysql_stmt_bind_param(stmt_selected, input_bind)) {
		fprintf(stderr, "get_orderinfo_stmt mysql_stmt_bind_param() failed\n");
		fprintf(stderr, "%s\n", mysql_stmt_error(stmt_selected));
		exit(EXIT_FAILURE);
	}

	if (mysql_stmt_execute(stmt_selected)) {
		fprintf(stderr, "get_orderinfo_stmt mysql_stmt_execute(), failed\n");
		fprintf(stderr, "%s\n", mysql_stmt_error(stmt_selected));
		exit(EXIT_FAILURE);
	}

	if (mysql_stmt_bind_result(stmt_selected, output_bind)) {
		fprintf(stderr, "get_orderinfo_stmt mysql_stmt_bind_result() failed\n");
		fprintf(stderr, "%s\n", mysql_stmt_error(stmt_selected));
		exit(EXIT_FAILURE);
	}

	if (mysql_stmt_store_result(stmt_selected)) {
		fprintf(stderr,
				"get_orderinfo_stmt mysql_stmt_store_result() failed\n");
		fprintf(stderr, "%s\n", mysql_stmt_error(stmt_selected));
		exit(EXIT_FAILURE);
	}

	int rownum = mysql_stmt_num_rows(stmt_selected);
	//printf("rownums: %d\n", rownum);

	if (rownum > 0) {
		while (!mysql_stmt_fetch(stmt_selected)) {
			OrderItem item;
			memset(&item, 0, sizeof(item));
			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_ORDERID]) {
				sprintf(item.orderID, "%d", output_orderID);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_TRAINID]) {
				sprintf(item.trainID, "%s", output_trainID);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_COMPARTMENTNUM]) {
				sprintf(item.compartmentNum, "%d", output_compartmentNum);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_SEATNUM]) {
				sprintf(item.seatNum, "%d", output_seatNum);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_NAME]) {
				sprintf(item.name, "%s", output_name);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_CREDITTYPE]) {
				sprintf(item.creditType, "%s", output_creditType);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_CREDITID]) {
				sprintf(item.creditID, "%s", output_creditID);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_DEPARTDATE]) {
				sprintf(item.departDate, "%04d-%02d-%02d",
						output_departdate.year, output_departdate.month,
						output_departdate.day);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_DEPARTSTATION]) {
				sprintf(item.departStation, "%s", output_departstation);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_ARRIVESTATION]) {
				sprintf(item.arriveStation, "%s", output_arrivestation);
			}

			if (!output_is_null[OUTPUT_TABLE_ORDERS_SELECT_PRICE]) {
				sprintf(item.price, "%-10.2f", output_price);
			}

			AddItem(item, orderlist);
		}
		result = true;
	} else {
		result = false;
	}
	return result;
}
